;; The first four lines of this file were added by Dracula.
;; They tell DrScheme that this is a Dracula Modular ACL2 program.
;; Leave these lines unchanged so that DrScheme can properly load this file.
#reader(planet "reader.rkt" ("cce" "dracula.plt") "modular" "lang")
(require "mbmptree.lisp")
(require "imirroring.lisp")

(module Mmirroring
  (import Ibmptree)
  
  ; Swaps the color values for pixel (lowest, curr) and pixel
  ; (highest, curr) and places them in the new tree.
  ; pre: tr - the bitmap tree
  ;      lowest - the first row to swap from
  ;      highest - the second row to swap with
  ;      maxCol - the max number of columns in the bitmap
  ; post: a new bmp-tree with the color values at the two
  ;       pixels swapped
  (defun mirror-vertical (tr lowest highest)
    ; Is the lowest row less than the highest row?
    (if (< lowest highest)
        ; yes, switch the colors of the two pixels and 
        ; add them to the new bmp-tree
        (let* ((newLowRow (get-row tr highest))
               (newHighRow (get-row tr lowest))
               (tempTree (insert-row tr lowest newLowRow))
               (newTree (insert-row tempTree highest newHighRow)))
          (mirror-vertical newTree (+ lowest 1) (- highest 1)))
        ; no, return the new tree
        tr))

  ; Swaps the color values for pixel (curr, lowest) and pixel
  ; (curr, highest) and places them in the new tree.
  ; pre: tr - the bitmap tree
  ;      lowest - the first column to swap from
  ;      highest - the second column to swap with
  ;      maxRow - the max number of rows in the bitmap
  ;      curr - the current row for swapping
  ; post: a new bmp-tree with the color values at the two
  ;       pixels swapped
  (defun mirror-horizontal (tr lowest highest maxRow curr)
    ; Is the lowest row less than the highest row?
    (if (< lowest highest)
        ; yes, is the current row less than or equal to the
        ; max row?
        (if (<= curr maxRow)
            ; yes, switch the colors of the two pixels and 
            ; add them to the new bmp-tree
            (let* ((newLowPixel (list curr lowest
                                      (get-pixel-color tr curr 
                                                       highest))) 
                   (newHighPixel (list curr highest
                                       (get-pixel-color tr curr 
                                                        lowest)))
                   (tempTree (insert-pixel tr newLowPixel))
                   (newTree (insert-pixel tempTree newHighPixel)))
              ; swap the colors for those pixels for the same 
              ; columns in the next row
              (mirror-horizontal newTree lowest highest maxRow 
                                 (+ curr 1)))
            ; no, swap the next two columns
            (mirror-horizontal tr (+ lowest 1) (- highest 1) 
                               maxRow 0))
        ; no, return the new tree
        tr))
  
  ; Flips the image horizontally or vertically depending on
  ; the value of orientation. Uses the mirror-horizontal and
  ; mirror-vertical functions.
  ; pre: tr - a bmp-tree
  ;      orientation - string equal to "vertical" for vertical
  ;                    flip or "horizontal" for horizontal flip
  ; post: a bmp-tree representation of the flipped image
  (defun mirror (tr orientation)
    ; Is tr a nonempty bmp-tree?
    ; And is orientation a string?
    (if (and (consp (get-header tr)) (stringp orientation))
        ; yes, flip vertical?
        (if (string-equal orientation "vertical")
            ; yes, get the total number of rows and the total number
            ; of columns in the bitmap
            (let* ((dimensions (get-dimensions tr))
                   (highRow (- (car dimensions) 1)))
              ; return the tree representation of the vertically
              ; flipped image
              (mirror-vertical tr 0 highRow))
            ; no, flip horizontal?
            (if (string-equal orientation "horizontal")
                ; yes, get the total number of rows and the total
                ; number of columns in the bitmap
                (let* ((dimensions (get-dimensions tr))
                       (highCol (- (cdr dimensions) 1))
                       (maxRow (- (car dimensions) 1)))
                  ; return the tree representation of the 
                  ; horizontally flipped image
                  (mirror-horizontal tr 0 highCol maxRow 0))
                ; no, return the unchanged tree
                tr))
        ; no, return the unchanged tree
        tr))
  
  (export Imirroring))
